﻿package net.libra.ui
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
	import net.libra.ui.base.BaseSprite;
	import net.libra.utils.Reflection;


	/**
	 * 简单按钮。
	 * @author elvisjiang
	 */
	public class EasyButton extends BaseSprite
	{

		public function get isSliderButton():Boolean
		{
			return _isSliderButton;
		}

		public function set isSliderButton(value:Boolean):void
		{
			_isSliderButton = value;
		}

		/**
		 * 创建一个按钮
		 * @param mc		按钮影片剪辑
		 * @param toggleMode	是否是可选择的按钮，true，则按钮可选择，false不可选
		 * @param allowSelectedOnce 是否只允许选择一次
		 */
		public static function createEasyButton ( mc : MovieClip , toggleMode : Boolean = false ,isSliderButton:Boolean = false) : EasyButton
		{
			var parent : DisplayObjectContainer = mc.parent;
			if (parent)
			{
				var depth : int = parent.getChildIndex ( mc );
				var x : int = mc.x,y : int = mc.y;
				var btn : EasyButton = new EasyButton ( mc , toggleMode ,isSliderButton);
				parent.addChildAt ( btn , depth );
				btn.x = x;
				btn.y = y;
				return btn;
			}
			return null;
		}

		/**
		 * 创建一个按钮
		 * @param child		按钮影片剪辑类
		 * @param toggleMode	是否是可选择的按钮，true，则按钮可选择，false不可选
		 */
		public static function createEasyButtonWithClass ( child : String , toggleMode : Boolean = false ) : EasyButton
		{
			return new EasyButton ( child , toggleMode );
		}

		// -------------------------------------------------------------------------
		private var mc : MovieClip;
		private var bg : MovieClip;

		private var rollover : Boolean;
		private var pressed : Boolean;
		private var enabled : Boolean;
		private var selected : Boolean;
		private var armed : Boolean;
		private var toggleMode : Boolean;
		private var group : ButtonGroup;

		private var text : String;

		public function get skin():MovieClip
		{
			return mc;
		}
		/**
		 * 创建一个按钮
		 * EasyButton(mc:MovieClip,toggleMode : Boolean = false)
		 * EasyButton(className:String,toggleMode : Boolean = false)
		 * @param child			一个影片剪辑或者一个类名
		 * @param toggleMode	是否是可选择的按钮，true，则按钮可选择，false不可选
		 * @param allowSelectedOnce 是否只允许选择一次
		 */
		public function EasyButton ( child : Object , toggleMode : Boolean = false ,isSliderButton:Boolean = false)
		{
			this.mouseChildren = this.mouseEnabled = true;
			this.focusRect = null;
			this.tabEnabled = false;
			this.mouseChildren = false;
			this.buttonMode = true;
			//
			this.rollover = false;
			this.pressed = false;
			this.selected = false;
			this.armed = false;
			this.enabled = true;
			this._isSliderButton = isSliderButton;
			this.toggleMode = toggleMode;

			try
			{
				if (child is String)
				{
					this.mc = Reflection.createDisplayObjectInstance ( child as String ) as MovieClip;
				}
				else
				{
					this.mc = child as MovieClip;
				}
				this.mc.gotoAndStop ( 1 );
				this.mc.mouseChildren = false;
				this.mc.x = 0;
				this.mc.y = 0;
				this.addChild ( this.mc );
			}
			catch(e : Error)
			{
				throw new Error ( "不存在指定的类。" );
			}

			//
			this.addEventListener ( MouseEvent.ROLL_OVER , this.__onBtnRollover );
			this.addEventListener ( MouseEvent.ROLL_OUT , this.__onBtnRollout );
			this.addEventListener ( MouseEvent.MOUSE_DOWN , this.__onBtnMouseDown );
			this.addEventListener ( MouseEvent.MOUSE_UP , this.__onBtnMouseUp );

			// 添加侦听
			for (var i : int = 0; i < 8; i ++)
			{
				this.mc.addFrameScript ( i , this.__onPaintMC );
			}
			this.layout ();
			this.paintUI ();
		}
		
		override public function destroy():void
		{
			this.removeEventListener ( MouseEvent.ROLL_OVER , this.__onBtnRollover );
			this.removeEventListener ( MouseEvent.ROLL_OUT , this.__onBtnRollout );
			this.removeEventListener ( MouseEvent.MOUSE_DOWN , this.__onBtnMouseDown );
			this.removeEventListener ( MouseEvent.MOUSE_UP , this.__onBtnMouseUp );
			if(this.parent){
				this.parent.removeChild(this);
			}
			super.destroy();
		}

		private function __onBtnRollover ( e : MouseEvent ) : void
		{
			if (this.pressed)
			{
				this.armed = true;
			}
			else
			{
				this.rollover = true;
			}
			this.paintUI ();
		}

		private var _isSliderButton:Boolean = false;
		public function setPressed():void
		{
			this.pressed = true;
			this.armed = true;
			this.paintUI ();
		}
		private function __onBtnRollout ( e : MouseEvent ) : void
		{
			if (this.pressed)
			{
				this.armed = false;
			}
			else
			{
				this.rollover = false;
			}
			this.paintUI ();
		}

		private function __onBtnMouseDown ( e : MouseEvent ) : void
		{
			this.pressed = true;
			this.armed = true;
			if (this.stage) this.stage.addEventListener ( MouseEvent.MOUSE_UP , this.__onStageMouseUp );
			if(this.stage && this.isSliderButton) this.stage.addEventListener(MouseEvent.MOUSE_MOVE,__onStageMouseMove);
			this.paintUI ();
		}
		private function __onStageMouseUp ( e : MouseEvent ) : void
		{
			this.pressed = false;
			this.armed = false;
			this.rollover = false;
			this.paintUI ();
			
			this.addEventListener ( MouseEvent.ROLL_OUT , this.__onBtnRollout );
			if (this.stage) this.stage.removeEventListener ( MouseEvent.MOUSE_UP , this.__onStageMouseUp );
		}
		protected function __onStageMouseMove(event:MouseEvent):void
		{
			this.removeEventListener ( MouseEvent.ROLL_OUT , this.__onBtnRollout );
		}
		
		private function __onBtnMouseUp ( e : MouseEvent ) : void
		{
			if (this.armed && this.toggleMode)
			{
				this.setSelected (  !this.selected );
			}
			this.pressed = false;
			this.armed = false;
			this.paintUI ();
			if (this.stage) this.stage.removeEventListener ( MouseEvent.MOUSE_UP , this.__onStageMouseUp );
		}

		private function __onPaintMC () : void
		{
			for (var i : int = 0; i < mc.numChildren; i ++)
			{
				var dis : DisplayObject = mc.getChildAt ( i );
				if (dis is TextField && this.text != null)
				{
					TextField ( dis ).text = this.text;
				}
				else if (dis is MovieClip)
				{
					MovieClip ( dis ).gotoAndStop ( this.getPaintFrame () );
				}
			}
		}

		override public function set useHandCursor ( value : Boolean ) : void
		{
			super.useHandCursor = true;
			value;
		}

		/**
		 * 设置按钮是否可用
		 * @param b		按钮是否可用
		 */
		public function setEnabled ( b : Boolean ) : void
		{
			this.mouseEnabled = b;
			this.enabled = b;
			this.paintUI ();
		}

		/**
		 * 返回按钮是否可用
		 * @return		按钮是否可用
		 */
		public function isEnabled () : Boolean
		{
			return this.enabled;
		}

		/**
		 * 设置是否选中按钮
		 * @param selected		是否选中按钮
		 */
		public function setSelected ( selected : Boolean ) : void
		{
			if (this.selected != selected)
			{
				if (this.group && this.toggleMode)
				{
					var oldSelected : Boolean = this.selected;
					this.group.setSelected ( selected , this );
					this.selected = this.group.isSelected ( this );
					// 如果选中的值改变了
					if (oldSelected != this.selected)
					{
						this.dispatchEvent ( new Event ( "select" ) );
					}
				}
				else
				{
					this.selected = selected;
				}
				this.paintUI ();
			}
		}

		/**
		 * 返回是否选中按钮
		 * @return		是否选中按钮
		 */
		public function isSelected () : Boolean
		{
			return this.selected;
		}

		/**
		 * 设置按钮背景
		 * setBackground(bg:MovieClip);
		 * setBackground(className:String)
		 * @param bg		影片剪辑或者类名
		 */
		public function setBackground ( bg : Object ) : void
		{
			if (this.bg)
			{
				this.removeChild ( this.bg );
			}
			// 设置背景影片剪辑
			if (bg is String)
			{
				this.bg = Reflection.createDisplayObjectInstance ( bg as String ) as MovieClip;
			}
			else
			{
				this.bg = bg as MovieClip;
			}
			//
			if (this.bg)
			{
				this.bg.x = 0;
				this.bg.y = 0;
				this.bg.gotoAndStop ( 1 );
				this.addChildAt ( this.bg , 0 );
			}
			this.layout ();
			this.paintUI ();
		}

		/**
		 * 设置按钮群组
		 * @param group		按钮群组
		 */
		public function setGroup ( group : ButtonGroup ) : void
		{
			this.group = group;
			this.group.appendButton ( this );
		}

		/**
		 * 返回按钮群组
		 * @return		按钮群组
		 */
		public function getGroup () : ButtonGroup
		{
			return this.group;
		}

		/**
		 * 设置按钮的文本
		 */
		public function setText ( text : String ) : void
		{
			this.text = text;
			__onPaintMC ();
			this.paintUI ();
		}

		/**
		 * 返回按钮的文本
		 */
		public function getText () : String
		{
			return this.text;
		}

		/**
		 * 显示外表
		 */
		private function paintUI () : void
		{
			var frame : int = this.getPaintFrame ();
			if (this.bg) this.paintBackground ( this.bg , frame );
			this.paintMC ( this.mc , frame );
		}

		private function getPaintFrame () : int
		{
			var frame : int = 0;
			if (! this.enabled)
			{
				frame = this.selected ? 8 : 4;
			}
			else if (this.pressed && this.armed)
			{
				frame = this.selected ? 7 : 3;
			}
			else if (this.rollover)
			{
				frame = this.selected ? 6 : 2;
			}
			else
			{
				frame = this.selected ? 5 : 1;
			}
			return frame;
		}

		private function paintBackground ( bg : MovieClip , frame : int ) : void
		{
			bg.gotoAndStop ( frame );
		}

		private function paintMC ( mc : MovieClip , frame : int ) : void
		{
			mc.gotoAndStop ( frame );
		}

		private function layout () : void
		{
			var width : int = 0;
			var height : int = 0;
			if (this.bg)
			{
				this.bg.x = 0;
				this.bg.y = 0;
				width = this.bg.width;
				height = this.bg.height;
			}
			// layout mc
			if (width == 0)
			{
				this.mc.x = 0;
				width = this.mc.width;
			}
			else
			{
				this.mc.x = (width - this.mc.width) / 2;
			}
			//
			if (height == 0)
			{
				this.mc.y = 0;
				height = this.mc.height;
			}
			else
			{
				this.mc.y = (height - this.mc.height) / 2;
			}

			//
			this.graphics.clear ();
			this.graphics.beginFill ( 0 , 0 );
			this.graphics.drawRect ( 0 , 0 , this.width , this.height );
			this.graphics.endFill ();
		}

		public function addSelectListener ( listener : Function , useCapture : Boolean = false , priority : int = 0 , useWeakReference : Boolean = false ) : void
		{
			this.addEventListener ( "select" , listener , useCapture , priority , useWeakReference );
		}

		public function removeSelectListener ( listener : Function , useCapture : Boolean = false ) : void
		{
			this.removeEventListener ( "select" , listener , useCapture );
		}
	}
}
